﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Studentpartners.Sightseeing.ViewModels;
using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Controls.Maps.Platform;
using System.Device.Location;

namespace Studentpartners.Sightseeing
{
    public partial class MainPage : PhoneApplicationPage
    {
        private GeoCoordinateWatcher _watcher;
        private Location _lastKnownPosition;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            DataContext = App.ViewModel;

            // Register as maps holder
            App.MapsPage = this;

            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        /// <summary>
        /// Loads viewmodel data.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (!App.ViewModel.IsDataLoaded)
            {
                App.ViewModel.LoadData();
                MapsControl.Children.Clear();

                foreach (SightViewModel item in App.ViewModel.Items)
                {
                    MapsControl.Children.Add(new Pushpin()
                    {
                        Content = item.Title,
                        Location = new Location() { Latitude = item.Latitude, Longitude = item.Longitude }
                    });
                }

                _watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default) { MovementThreshold = 100 };
                _watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(_watcher_StatusChanged);
                _watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(_watcher_PositionChanged);
            }

            ResetMap();

            // Only start watcher if the user has confirmed gps usage
            if (App.GpsEnabled)
            {
                _watcher.Start();
            }
        }

        #region GeoPositionWatcher Events

        void _watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            // Run on UI Thread
            Deployment.Current.Dispatcher.BeginInvoke(() => MyPositionChanged(e));
        }

        void _watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            // Run on UI Thread
            Deployment.Current.Dispatcher.BeginInvoke(() => MyStatusChanged(e));
        }

        /// <summary>
        /// Updates the last known position and moves the "your position" pin.
        /// </summary>
        /// <param name="e"></param>
        private void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            // Update the map to show the current location 
            _lastKnownPosition = new Location() { Latitude = e.Position.Location.Latitude, Longitude = e.Position.Location.Longitude };

            // Update pushpin location 
            //MapLayer.SetPosition(YouPin, _myPosition);
            //YouPin.Visibility = System.Windows.Visibility.Visible;
        }

        /// <summary>
        /// Show watcher status in system tray.
        /// </summary>
        /// <param name="e"></param>
        private void MyStatusChanged(GeoPositionStatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                case GeoPositionStatus.Disabled:
                    TrayBar.IsVisible = false;
                    MessageBox.Show("Kartensuche wurde deaktiviert. Bitte aktiviere die Kartensuche in deinen Handyeinstellungen.");
                    break;
                case GeoPositionStatus.Initializing:
                    TrayBar.Text = "Position wird ermittelt";
                    TrayBar.IsVisible = true;
                    break;
                case GeoPositionStatus.NoData:
                    TrayBar.Text = "";
                    TrayBar.IsVisible = false;
                    MessageBox.Show("Position konnte nicht ermittelt werden.");
                    ResetMap();
                    break;
                case GeoPositionStatus.Ready:
                    TrayBar.Text = "";
                    TrayBar.IsVisible = false;
                    break;
                default:
                    TrayBar.Text = "";
                    TrayBar.IsVisible = false;
                    MessageBox.Show("Position konnte nicht ermittelt werden.");
                    ResetMap();
                    break;
            }
        }

        public void SetMapPosition(Location location)
        {
            MapsControl.SetView(location, 13.5);
        }

        /// <summary>
        /// Centers the map view on the current gps position.
        /// </summary>
        void ResetMap()
        {
            Location newLocation = new Location() { Latitude = ((MainViewModel)this.DataContext).Items[0].Latitude, Longitude = ((MainViewModel)this.DataContext).Items[0].Longitude };
            MapsControl.SetView(newLocation, 12);

            //update pushpin location and show 
            //MapLayer.SetPosition(YouPin, newLocation);
            //YouPin.Visibility = System.Windows.Visibility.Collapsed;
        }

        #endregion

        #region ApplicationBar Events

        private void FindMe_Click(object sender, EventArgs e)
        {
            if (App.GpsEnabled)
            {
                _watcher.Start();
                if (null != _lastKnownPosition)
                    MapsControl.SetView(_lastKnownPosition, 12.5);
            }
            else
            {
                MessageBox.Show("Positionsdaten wurden deaktiviert. Bitte aktivieren Sie die Positionsdaten in den Einstellungen.");
            }

        }

        private void AppBar_Info_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/InfoPage.xaml", UriKind.Relative));
        }

        #endregion
    }
}